import React, { FC, useContext, useEffect, useState } from "react";
import { useStyle } from "./useStyle";
import { ThemeContext } from "../theme";
import dayjs from "dayjs";
import DateTimeRangeBody from "./components/Body";
import DataTimeRangeHeader from "./components/Header";
import DateTimeRangeFooter from "./components/Footer";
import TimeValues from "./components/TimeValues";
import DataTimeRangeTrigger from "./components/Trigger";
import Dropdown from "rc-dropdown";
import type { DateType, DayType, Value } from "./type";
import { getInitStateValue } from "./utils";
import type { DateTimeRangeProps } from "./type";

const DateTimeRange: FC<DateTimeRangeProps> = (props) => {
  const {
    value,
    onChange,
    disabled,
    disabledTime = false,
    getPopupContainer,
  } = props;
  const { fontSize } = useContext(ThemeContext);
  const classes = useStyle({ fontSize });
  const [visible, setVisible] = useState<boolean>(false);
  const [selectedDate, setSelectedDate] = useState<[DateType, DateType]>([
    null,
    null,
  ]);
  const [viewDate, setViewDate] = useState<DayType>(dayjs());
  const initStateValue = () => {
    const [start, end] = getInitStateValue(value);
    const viewValue = start ?? end;
    const view = viewValue ? dayjs(viewValue) : dayjs();
    setViewDate(view);

    const selectedStart = start ? dayjs(start) : null;
    const selectedEnd = end ? dayjs(end) : null;
    setSelectedDate([selectedStart, selectedEnd]);
  };
  useEffect(() => {
    initStateValue();
  }, [value]);
  const onTrigger = () => setVisible(!visible);
  const handleSelectedDate = (value: [DateType, DateType]) =>
    setSelectedDate(value);
  const handleViewDate = (value: DayType) => setViewDate(value);
  const handleChange = () => {
    const isUnValidDate = isConfirmBtnDisabled();
    if (isUnValidDate) {
      return;
    }
    const [startDate, endDate] = selectedDate;
    const startV = startDate?.valueOf();
    const endV = endDate?.valueOf();
    if (startV && endV) {
      const value =
        endV > startV ? ([startV, endV] as Value) : ([endV, startV] as Value);
      onChange?.(value);
      onTrigger();
    }
  };
  const handleClear = () => {
    onChange?.(null);
    setSelectedDate([null, null]);
    onTrigger();
  };
  const isConfirmBtnDisabled = () => {
    const [start, end] = selectedDate;
    return !start || !end || start.isSame(end);
  };
  const onVisibleChange = (visible: boolean) => {
    if (disabled) return;
    visible && initStateValue();
    setVisible(visible);
  };
  return (
    <div className={classes.dataTimeRange}>
      <Dropdown
        trigger={["click"]}
        onVisibleChange={onVisibleChange}
        visible={visible}
        getPopupContainer={getPopupContainer}
        overlay={
          <div className={classes.container} role="container">
            <TimeValues
              selectedDate={selectedDate}
              handleSelectedDate={handleSelectedDate}
              disabledTime={disabledTime}
            />
            <DataTimeRangeHeader
              viewDate={viewDate}
              setViewDate={handleViewDate}
            />
            <DateTimeRangeBody
              selectedDate={selectedDate}
              handleSelectedDate={handleSelectedDate}
              viewDate={viewDate}
            />
            <DateTimeRangeFooter
              onClear={handleClear}
              onChange={handleChange}
              disabled={isConfirmBtnDisabled()}
            />
          </div>
        }
      >
        <div className={classes.triggerContainer}>
          <DataTimeRangeTrigger onTrigger={onTrigger} {...props} />
        </div>
      </Dropdown>
    </div>
  );
};

export default DateTimeRange;
